package csharp.cauth.commands;

import java.util.logging.Level;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import com.nijiko.permissions.PermissionHandler;

import csharp.cauth.CAuth;
import csharp.cauth.Language;
import csharp.cauth.PlayersSL;
import csharp.cauth.PluginConfig;
import csharp.cauth.properties.PlayerProp;
import csharp.cauth.utils.Log;
import csharp.cauth.utils.MD5;

/**
 * @author Ярослав (CSharp) "/register" command. Used for player registration on
 *         the server. Checks if player IP is registered for now time, if IP is
 *         dynamic checks login.
 */
public class CARegister implements CommandExecutor
{
	private static CAuth plugin;

	public CARegister(CAuth cAuth)
	{
		CARegister.plugin = cAuth;
	}

	@Override
	public boolean onCommand(CommandSender sender, Command command,
			String label, String[] split)
	{
		if (sender instanceof Player)
		{
			Player player = (Player) sender;

			if (PluginConfig.usePermissions)
				return permissionsExecutor(player, split);
			else
				return executor(player, split);
		}

		return true;
	}

	private boolean executor(Player player, String[] split)
	{
		if (split.length > 1)
		{
			if (!CAuth.authorized.contains(player))
			{
				String ip = player.getAddress().getAddress().getHostAddress();

				PlayerProp playerProp = new PlayerProp(player.getName(),
						MD5.getHash(split[0]), ip, player.getLocation());

				if (!CAuth.players.contains(playerProp))
				{
					for (PlayerProp playerProp2 : CAuth.players)
					{
						/*
						 * if (playerProp2.getIp().equalsIgnoreCase(
						 * playerProp.getIp())) { player.sendMessage(
						 * "[CAuth] This IP is registred at now time.");
						 * 
						 * return true; }
						 */

						if (playerProp2.getLogin().equalsIgnoreCase(
								playerProp.getLogin()))
						{
							player.sendMessage("[CAuth] "
									+ Language.THIS_LOGIN_IS_REGISTRED_AT_NOW_TIME);

							return true;
						}
					}

					Integer check = CAuth.ipCounter.get(ip);

					if (check != null)
					{
						if (check >= PluginConfig.accountsPerIP)
						{
							player.sendMessage("[CAuth] "
									+ Language.THIS_IP_ADDRESS_HAS_EXCEEDED_THE_LIMIT_OF_REGISTRATIONS);

							return true;
						}
					}

					if (split[0].equalsIgnoreCase(split[1]))
					{
						if (PluginConfig.useMySQL)
							playerProp.setId(PlayersSL.create(
									playerProp.getLogin(),
									playerProp.getPassword(),
									playerProp.getIp()));
						else
							PlayersSL.savePlayers();

						CAuth.players.add(playerProp);

						player.sendMessage("[CAuth] "
								+ Language.YOU_SUCCESSFULLY_REGISTRED_ON_THE_SERVER);

						if (!CAuth.ipCounter.containsKey(ip))
						{
							CAuth.ipCounter.put(ip, 1);
						}
						else
						{
							Integer count = CAuth.ipCounter.get(ip);

							CAuth.ipCounter.put(ip, count + 1);
						}
					}
					else
					{
						player.sendMessage("[CAuth] "
								+ Language.PASSWORDS_NOT_EQUALS);
					}
				}
				else
				{
					player.sendMessage("[CAuth] "
							+ Language.YOU_IS_REGISTRED_AT_NOW_TIME);
				}
			}
			else
			{
				player.sendMessage("[CAuth] "
						+ Language.YOU_IS_AUTHORIZED_AT_NOW_TIME);
			}

			return true;
		}

		return false;
	}

	private boolean permissionsExecutor(Player player, String[] split)
	{
		PermissionHandler permissionHandler = CAuth.permissionHandler;

		if (permissionHandler == null)
		{
			Log.log(Level.INFO,
					"No permissions plugin installed, default command executor selected.");

			PluginConfig.usePermissions = false;

			return executor(player, split);
		}

		if (permissionHandler.has(player, "CAuth.register"))
		{
			if (split.length > 1)
			{
				if (!CAuth.authorized.contains(player))
				{
					String ip = player.getAddress().getAddress()
							.getHostAddress();

					PlayerProp playerProp = new PlayerProp(player.getName(),
							MD5.getHash(split[0]), ip, player.getLocation());

					if (!CAuth.players.contains(playerProp))
					{
						for (PlayerProp playerProp2 : CAuth.players)
						{
							/*
							 * if (playerProp2.getIp().equalsIgnoreCase(
							 * playerProp.getIp())) { player.sendMessage(
							 * "[CAuth] This IP is registred at now time.");
							 * 
							 * return true; }
							 */

							if (playerProp2.getLogin().equalsIgnoreCase(
									playerProp.getLogin()))
							{
								player.sendMessage("[CAuth] "
										+ Language.THIS_LOGIN_IS_REGISTRED_AT_NOW_TIME);

								return true;
							}
						}

						Integer check = CAuth.ipCounter.get(ip);

						if (check != null)
						{
							if (check >= PluginConfig.accountsPerIP)
							{
								player.sendMessage("[CAuth] "
										+ Language.THIS_IP_ADDRESS_HAS_EXCEEDED_THE_LIMIT_OF_REGISTRATIONS);

								return true;
							}
						}

						if (split[0].equalsIgnoreCase(split[1]))
						{
							if (PluginConfig.useMySQL)
								playerProp.setId(PlayersSL.create(
										playerProp.getLogin(),
										playerProp.getPassword(),
										playerProp.getIp()));
							else
								PlayersSL.savePlayers();

							CAuth.players.add(playerProp);

							player.sendMessage("[CAuth] "
									+ Language.YOU_SUCCESSFULLY_REGISTRED_ON_THE_SERVER);

							if (!CAuth.ipCounter.containsKey(ip))
							{
								CAuth.ipCounter.put(ip, 1);
							}
							else
							{
								Integer count = CAuth.ipCounter.get(ip);

								CAuth.ipCounter.put(ip, count + 1);
							}
						}
						else
						{
							player.sendMessage("[CAuth] "
									+ Language.PASSWORDS_NOT_EQUALS);
						}
					}
					else
					{
						player.sendMessage("[CAuth] "
								+ Language.YOU_IS_REGISTRED_AT_NOW_TIME);
					}
				}
				else
				{
					player.sendMessage("[CAuth] "
							+ Language.YOU_IS_AUTHORIZED_AT_NOW_TIME);
				}

				return true;
			}
		}

		return false;
	}
}
